package test.restful;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Collection;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.wink.server.utils.LinkBuilders;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

@Path("tasks")
public class TasksResource {
    private static final String TASK = "tasks";
    private static final String ITEM_PATH = "{tasks}";
    private static final String ENCODING = "UTF-8";

    private Task createTask(MultivaluedMap<String, String> 
        formData) throws UnsupportedEncodingException {

        String id = formData.getFirst("id");
        String name = URLDecoder.decode(formData.getFirst("name"), ENCODING);
        String dueDate = URLDecoder.decode(formData.getFirst("dueDate"), ENCODING);
        String notes = URLDecoder.decode(formData.getFirst("notes"), ENCODING);
        boolean complete = Boolean.parseBoolean(formData.getFirst("complete"));

        Task task = new Task(id, name, notes, dueDate);
        task.setComplete(complete);

        return task;
    }

    private JSONObject createJSONObject(Task task) throws JSONException {
        JSONObject obj = new JSONObject();
        obj.put("name", task.getName());
        obj.put("notes", task.getNotes());
        obj.put("dueDate", task.getDueDate());
        obj.put("complete", task.isComplete());
        obj.put("id", task.getId());
        return obj;
    }

    @GET
    @Produces( { MediaType.APPLICATION_JSON })
    public JSONArray getTasks() {
        JSONArray result = new JSONArray();

        Collection<Task> tasks = TaskManager.getInstance().getTasks();

        for (Task task : tasks) {
            try {
                result.put(createJSONObject(task));
            } catch (JSONException e) {
                e.printStackTrace();
                throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
            }
        }

        return result;
    }

    @Path(ITEM_PATH)
    @GET
    @Produces( { MediaType.APPLICATION_JSON })
    public JSONObject getTask(@Context LinkBuilders link, @Context UriInfo uri,
            @PathParam(TASK) String taskId) {

        Task task = TaskManager.getInstance().getTask(taskId);

        if (task == null) {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }

        JSONObject result;
        try {
            result = createJSONObject(task);
        } catch (JSONException e) {
            e.printStackTrace();
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
        return result;
    }

    @POST
    @Consumes( { MediaType.APPLICATION_FORM_URLENCODED })
    @Produces( { MediaType.APPLICATION_JSON })
    public JSONObject createTask(MultivaluedMap<String, String> formData,
            @Context UriInfo uriInfo, @Context LinkBuilders linksBuilders) {

        Task newTask;
        JSONObject obj;

        try {
            
            newTask = createTask(formData);
            TaskManager.getInstance().addTask(newTask.getId(), newTask);
            obj = createJSONObject(newTask);
            
        } catch (Exception e) {
            e.printStackTrace();
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }

        return obj;

    }


}
